(function (global, factory) {
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
  typeof define === 'function' && define.amd ? define(['exports'], factory) :
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.monitorSdk = {}));
})(this, (function (exports) { 'use strict';

  function ownKeys(object, enumerableOnly) {
    var keys = Object.keys(object);

    if (Object.getOwnPropertySymbols) {
      var symbols = Object.getOwnPropertySymbols(object);
      enumerableOnly && (symbols = symbols.filter(function (sym) {
        return Object.getOwnPropertyDescriptor(object, sym).enumerable;
      })), keys.push.apply(keys, symbols);
    }

    return keys;
  }

  function _objectSpread2(target) {
    for (var i = 1; i < arguments.length; i++) {
      var source = null != arguments[i] ? arguments[i] : {};
      i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
        _defineProperty(target, key, source[key]);
      }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
        Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
      });
    }

    return target;
  }

  function _regeneratorRuntime() {
    /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */

    _regeneratorRuntime = function () {
      return exports;
    };

    var exports = {},
        Op = Object.prototype,
        hasOwn = Op.hasOwnProperty,
        $Symbol = "function" == typeof Symbol ? Symbol : {},
        iteratorSymbol = $Symbol.iterator || "@@iterator",
        asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator",
        toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";

    function define(obj, key, value) {
      return Object.defineProperty(obj, key, {
        value: value,
        enumerable: !0,
        configurable: !0,
        writable: !0
      }), obj[key];
    }

    try {
      define({}, "");
    } catch (err) {
      define = function (obj, key, value) {
        return obj[key] = value;
      };
    }

    function wrap(innerFn, outerFn, self, tryLocsList) {
      var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator,
          generator = Object.create(protoGenerator.prototype),
          context = new Context(tryLocsList || []);
      return generator._invoke = function (innerFn, self, context) {
        var state = "suspendedStart";
        return function (method, arg) {
          if ("executing" === state) throw new Error("Generator is already running");

          if ("completed" === state) {
            if ("throw" === method) throw arg;
            return doneResult();
          }

          for (context.method = method, context.arg = arg;;) {
            var delegate = context.delegate;

            if (delegate) {
              var delegateResult = maybeInvokeDelegate(delegate, context);

              if (delegateResult) {
                if (delegateResult === ContinueSentinel) continue;
                return delegateResult;
              }
            }

            if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) {
              if ("suspendedStart" === state) throw state = "completed", context.arg;
              context.dispatchException(context.arg);
            } else "return" === context.method && context.abrupt("return", context.arg);
            state = "executing";
            var record = tryCatch(innerFn, self, context);

            if ("normal" === record.type) {
              if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue;
              return {
                value: record.arg,
                done: context.done
              };
            }

            "throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg);
          }
        };
      }(innerFn, self, context), generator;
    }

    function tryCatch(fn, obj, arg) {
      try {
        return {
          type: "normal",
          arg: fn.call(obj, arg)
        };
      } catch (err) {
        return {
          type: "throw",
          arg: err
        };
      }
    }

    exports.wrap = wrap;
    var ContinueSentinel = {};

    function Generator() {}

    function GeneratorFunction() {}

    function GeneratorFunctionPrototype() {}

    var IteratorPrototype = {};
    define(IteratorPrototype, iteratorSymbol, function () {
      return this;
    });
    var getProto = Object.getPrototypeOf,
        NativeIteratorPrototype = getProto && getProto(getProto(values([])));
    NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype);
    var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype);

    function defineIteratorMethods(prototype) {
      ["next", "throw", "return"].forEach(function (method) {
        define(prototype, method, function (arg) {
          return this._invoke(method, arg);
        });
      });
    }

    function AsyncIterator(generator, PromiseImpl) {
      function invoke(method, arg, resolve, reject) {
        var record = tryCatch(generator[method], generator, arg);

        if ("throw" !== record.type) {
          var result = record.arg,
              value = result.value;
          return value && "object" == typeof value && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) {
            invoke("next", value, resolve, reject);
          }, function (err) {
            invoke("throw", err, resolve, reject);
          }) : PromiseImpl.resolve(value).then(function (unwrapped) {
            result.value = unwrapped, resolve(result);
          }, function (error) {
            return invoke("throw", error, resolve, reject);
          });
        }

        reject(record.arg);
      }

      var previousPromise;

      this._invoke = function (method, arg) {
        function callInvokeWithMethodAndArg() {
          return new PromiseImpl(function (resolve, reject) {
            invoke(method, arg, resolve, reject);
          });
        }

        return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg();
      };
    }

    function maybeInvokeDelegate(delegate, context) {
      var method = delegate.iterator[context.method];

      if (undefined === method) {
        if (context.delegate = null, "throw" === context.method) {
          if (delegate.iterator.return && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method)) return ContinueSentinel;
          context.method = "throw", context.arg = new TypeError("The iterator does not provide a 'throw' method");
        }

        return ContinueSentinel;
      }

      var record = tryCatch(method, delegate.iterator, context.arg);
      if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel;
      var info = record.arg;
      return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel);
    }

    function pushTryEntry(locs) {
      var entry = {
        tryLoc: locs[0]
      };
      1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry);
    }

    function resetTryEntry(entry) {
      var record = entry.completion || {};
      record.type = "normal", delete record.arg, entry.completion = record;
    }

    function Context(tryLocsList) {
      this.tryEntries = [{
        tryLoc: "root"
      }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0);
    }

    function values(iterable) {
      if (iterable) {
        var iteratorMethod = iterable[iteratorSymbol];
        if (iteratorMethod) return iteratorMethod.call(iterable);
        if ("function" == typeof iterable.next) return iterable;

        if (!isNaN(iterable.length)) {
          var i = -1,
              next = function next() {
            for (; ++i < iterable.length;) if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next;

            return next.value = undefined, next.done = !0, next;
          };

          return next.next = next;
        }
      }

      return {
        next: doneResult
      };
    }

    function doneResult() {
      return {
        value: undefined,
        done: !0
      };
    }

    return GeneratorFunction.prototype = GeneratorFunctionPrototype, define(Gp, "constructor", GeneratorFunctionPrototype), define(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) {
      var ctor = "function" == typeof genFun && genFun.constructor;
      return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name));
    }, exports.mark = function (genFun) {
      return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun;
    }, exports.awrap = function (arg) {
      return {
        __await: arg
      };
    }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () {
      return this;
    }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) {
      void 0 === PromiseImpl && (PromiseImpl = Promise);
      var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl);
      return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) {
        return result.done ? result.value : iter.next();
      });
    }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () {
      return this;
    }), define(Gp, "toString", function () {
      return "[object Generator]";
    }), exports.keys = function (object) {
      var keys = [];

      for (var key in object) keys.push(key);

      return keys.reverse(), function next() {
        for (; keys.length;) {
          var key = keys.pop();
          if (key in object) return next.value = key, next.done = !1, next;
        }

        return next.done = !0, next;
      };
    }, exports.values = values, Context.prototype = {
      constructor: Context,
      reset: function (skipTempReset) {
        if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined);
      },
      stop: function () {
        this.done = !0;
        var rootRecord = this.tryEntries[0].completion;
        if ("throw" === rootRecord.type) throw rootRecord.arg;
        return this.rval;
      },
      dispatchException: function (exception) {
        if (this.done) throw exception;
        var context = this;

        function handle(loc, caught) {
          return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught;
        }

        for (var i = this.tryEntries.length - 1; i >= 0; --i) {
          var entry = this.tryEntries[i],
              record = entry.completion;
          if ("root" === entry.tryLoc) return handle("end");

          if (entry.tryLoc <= this.prev) {
            var hasCatch = hasOwn.call(entry, "catchLoc"),
                hasFinally = hasOwn.call(entry, "finallyLoc");

            if (hasCatch && hasFinally) {
              if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0);
              if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc);
            } else if (hasCatch) {
              if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0);
            } else {
              if (!hasFinally) throw new Error("try statement without catch or finally");
              if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc);
            }
          }
        }
      },
      abrupt: function (type, arg) {
        for (var i = this.tryEntries.length - 1; i >= 0; --i) {
          var entry = this.tryEntries[i];

          if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) {
            var finallyEntry = entry;
            break;
          }
        }

        finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null);
        var record = finallyEntry ? finallyEntry.completion : {};
        return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record);
      },
      complete: function (record, afterLoc) {
        if ("throw" === record.type) throw record.arg;
        return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel;
      },
      finish: function (finallyLoc) {
        for (var i = this.tryEntries.length - 1; i >= 0; --i) {
          var entry = this.tryEntries[i];
          if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel;
        }
      },
      catch: function (tryLoc) {
        for (var i = this.tryEntries.length - 1; i >= 0; --i) {
          var entry = this.tryEntries[i];

          if (entry.tryLoc === tryLoc) {
            var record = entry.completion;

            if ("throw" === record.type) {
              var thrown = record.arg;
              resetTryEntry(entry);
            }

            return thrown;
          }
        }

        throw new Error("illegal catch attempt");
      },
      delegateYield: function (iterable, resultName, nextLoc) {
        return this.delegate = {
          iterator: values(iterable),
          resultName: resultName,
          nextLoc: nextLoc
        }, "next" === this.method && (this.arg = undefined), ContinueSentinel;
      }
    }, exports;
  }

  function _typeof(obj) {
    "@babel/helpers - typeof";

    return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) {
      return typeof obj;
    } : function (obj) {
      return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
    }, _typeof(obj);
  }

  function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
    try {
      var info = gen[key](arg);
      var value = info.value;
    } catch (error) {
      reject(error);
      return;
    }

    if (info.done) {
      resolve(value);
    } else {
      Promise.resolve(value).then(_next, _throw);
    }
  }

  function _asyncToGenerator(fn) {
    return function () {
      var self = this,
          args = arguments;
      return new Promise(function (resolve, reject) {
        var gen = fn.apply(self, args);

        function _next(value) {
          asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
        }

        function _throw(err) {
          asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
        }

        _next(undefined);
      });
    };
  }

  function _classCallCheck(instance, Constructor) {
    if (!(instance instanceof Constructor)) {
      throw new TypeError("Cannot call a class as a function");
    }
  }

  function _defineProperties(target, props) {
    for (var i = 0; i < props.length; i++) {
      var descriptor = props[i];
      descriptor.enumerable = descriptor.enumerable || false;
      descriptor.configurable = true;
      if ("value" in descriptor) descriptor.writable = true;
      Object.defineProperty(target, descriptor.key, descriptor);
    }
  }

  function _createClass(Constructor, protoProps, staticProps) {
    if (protoProps) _defineProperties(Constructor.prototype, protoProps);
    if (staticProps) _defineProperties(Constructor, staticProps);
    Object.defineProperty(Constructor, "prototype", {
      writable: false
    });
    return Constructor;
  }

  function _defineProperty(obj, key, value) {
    if (key in obj) {
      Object.defineProperty(obj, key, {
        value: value,
        enumerable: true,
        configurable: true,
        writable: true
      });
    } else {
      obj[key] = value;
    }

    return obj;
  }

  function _slicedToArray(arr, i) {
    return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();
  }

  function _arrayWithHoles(arr) {
    if (Array.isArray(arr)) return arr;
  }

  function _iterableToArrayLimit(arr, i) {
    var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];

    if (_i == null) return;
    var _arr = [];
    var _n = true;
    var _d = false;

    var _s, _e;

    try {
      for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {
        _arr.push(_s.value);

        if (i && _arr.length === i) break;
      }
    } catch (err) {
      _d = true;
      _e = err;
    } finally {
      try {
        if (!_n && _i["return"] != null) _i["return"]();
      } finally {
        if (_d) throw _e;
      }
    }

    return _arr;
  }

  function _unsupportedIterableToArray(o, minLen) {
    if (!o) return;
    if (typeof o === "string") return _arrayLikeToArray(o, minLen);
    var n = Object.prototype.toString.call(o).slice(8, -1);
    if (n === "Object" && o.constructor) n = o.constructor.name;
    if (n === "Map" || n === "Set") return Array.from(o);
    if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
  }

  function _arrayLikeToArray(arr, len) {
    if (len == null || len > arr.length) len = arr.length;

    for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];

    return arr2;
  }

  function _nonIterableRest() {
    throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
  }

  function _createForOfIteratorHelper(o, allowArrayLike) {
    var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];

    if (!it) {
      if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
        if (it) o = it;
        var i = 0;

        var F = function () {};

        return {
          s: F,
          n: function () {
            if (i >= o.length) return {
              done: true
            };
            return {
              done: false,
              value: o[i++]
            };
          },
          e: function (e) {
            throw e;
          },
          f: F
        };
      }

      throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
    }

    var normalCompletion = true,
        didErr = false,
        err;
    return {
      s: function () {
        it = it.call(o);
      },
      n: function () {
        var step = it.next();
        normalCompletion = step.done;
        return step;
      },
      e: function (e) {
        didErr = true;
        err = e;
      },
      f: function () {
        try {
          if (!normalCompletion && it.return != null) it.return();
        } finally {
          if (didErr) throw err;
        }
      }
    };
  }

  var cache = [];
  function getCache() {
    return cache;
  }
  function addCache(data) {
    cache.push(data);
  }
  function clearCache() {
    cache.length = 0;
  }

  var timer = null;
  /**
   * 上报
   * @param {*} type 
   * @param {*} params 
   */

  function lazyReport(type, params) {
    var appId = window['_monitor_app_id_'];
    var userId = window['_monitor_user_id_'];
    var delay = window['_monitor_delay_'];
    var userinfo = window['_monitor_user_info_'];
    console.log('reportData', params);
    var logParams = {
      appId: appId,
      // 项目的appId
      userId: userId,
      // 用户id
      userinfo: userinfo,
      type: type,
      // error/action/visit/user
      data: params,
      // 上报的数据
      currentTime: new Date().getTime(),
      // 时间戳
      currentPage: window.location.href,
      // 当前页面
      ua: navigator.userAgent // ua信息

    };
    var logParamsString = JSON.stringify(logParams);
    addCache(logParamsString);
    var data = getCache();

    if (delay === 0) {
      // delay=0相当于不做延迟上报
      report$1(data);
      return;
    }

    if (data.length > 10) {
      report$1(data);
      clearTimeout(timer);
      return;
    }

    clearTimeout(timer);
    timer = setTimeout(function () {
      report$1(data);
    }, delay);
  }
  function report$1(data) {
    var url = window['_monitor_report_url_']; // ------- fetch方式上报 -------
    // 跨域问题
    // fetch(url, {
    //   method: 'POST',
    //   body: JSON.stringify(data),
    //   headers: {
    //     'Content-Type': 'application/json',
    //   },
    // }).then(res => {
    //   console.log(res);
    // }).catch(err => {
    //   console.error(err);
    // })
    // ------- navigator/img方式上报 -------
    // 不会有跨域问题

    if (navigator.sendBeacon) {
      // 支持sendBeacon的浏览器
      navigator.sendBeacon(url, JSON.stringify(data));
    } else {
      // 不支持sendBeacon的浏览器
      var oImage = new Image();
      oImage.src = "".concat(url, "?logs=").concat(data);
    }

    clearCache();
  }

  /**
   * 手动上报
   */

  function tracker(actionType, data) {
    lazyReport('action', {
      actionType: actionType,
      data: data
    });
  }
  /**
   * 自动上报
   */

  function autoTrackerReport() {
    // 自动上报
    document.body.addEventListener('click', function (e) {
      var clickedDom = e.target; // 获取标签上的data-target属性的值

      var target = clickedDom === null || clickedDom === void 0 ? void 0 : clickedDom.getAttribute('data-target'); // 获取标签上的data-no属性的值

      var no = clickedDom === null || clickedDom === void 0 ? void 0 : clickedDom.getAttribute('data-no'); // 避免重复上报

      if (no) {
        return;
      }

      if (target) {
        lazyReport('action', {
          actionType: 'manual',
          data: target
        });
      } else {
        // 获取被点击元素的dom路径
        var result = getImgButtonPath(clickedDom);

        if (result) {
          var node = result.node;
          lazyReport('action', {
            actionType: node,
            data: result
          });
        }
      }
    }, false);
  }

  /**
   * history路由监听
   */

  function historyPageTrackerReport() {
    var beforeTime = Date.now(); // 进入页面的时间

    var beforePage = ''; // 上一个页面
    // 获取在某个页面的停留时间

    function getStayTime() {
      var curTime = Date.now();
      var stayTime = curTime - beforeTime;
      beforeTime = curTime;
      return stayTime;
    }
    /**
     * 重写pushState和replaceState方法
     * @param {*} name 
     * @returns 
     */


    var createHistoryEvent = function createHistoryEvent(name) {
      // 拿到原来的处理方法
      var origin = window.history[name];
      return function (event) {
        // if (name === 'replaceState') {
        //   const { current } = event;
        //   const pathName = location.pathname;
        //   if (current === pathName) {
        //     let res = origin.apply(this, arguments);
        //     return res;
        //   }
        // }
        var res = origin.apply(this, arguments);
        var e = new Event(name);
        e.arguments = arguments;
        window.dispatchEvent(e);
        return res;
      };
    }; // history.pushState


    window.addEventListener('pushState', function () {
      listener();
    }); // history.replaceState

    window.addEventListener('replaceState', function () {
      listener();
    });
    window.history.pushState = createHistoryEvent('pushState');
    window.history.replaceState = createHistoryEvent('replaceState');

    function listener() {
      var stayTime = getStayTime(); // 停留时间

      var currentPage = window.location.href; // 页面路径

      lazyReport('visit', {
        stayTime: stayTime,
        page: beforePage
      });
      beforePage = currentPage;
    } // 页面load监听


    window.addEventListener('load', function () {
      // beforePage = location.href;
      listener();
    }); // unload监听

    window.addEventListener('unload', function () {
      listener();
    }); // history.go()、history.back()、history.forward() 监听

    window.addEventListener('popstate', function () {
      listener();
    });
  }
  /**
   * hash路由监听
   */

  function hashPageTrackerReport() {
    var beforeTime = Date.now(); // 进入页面的时间

    var beforePage = ''; // 上一个页面

    function getStayTime() {
      var curTime = Date.now();
      var stayTime = curTime - beforeTime;
      beforeTime = curTime;
      return stayTime;
    }

    function listener() {
      var stayTime = getStayTime();
      var currentPage = window.location.href;
      lazyReport('visit', {
        stayTime: stayTime,
        page: beforePage
      });
      beforePage = currentPage;
    } // hash路由监听


    window.addEventListener('hashchange', function () {
      listener();
    }); // 页面load监听

    window.addEventListener('load', function () {
      listener();
    });

    var createHistoryEvent = function createHistoryEvent(name) {
      var origin = window.history[name];
      return function (event) {
        // if (name === 'replaceState') {
        //   const { current } = event;
        //   const pathName = location.pathname;
        //   if (current === pathName) {
        //     let res = origin.apply(this, arguments);
        //     return res;
        //   }
        // }
        var res = origin.apply(this, arguments);
        var e = new Event(name);
        e.arguments = arguments;
        window.dispatchEvent(e);
        return res;
      };
    };

    window.history.pushState = createHistoryEvent('pushState'); // history.pushState

    window.addEventListener('pushState', function () {
      listener();
    });
  }

  /**
   * 全局错误捕获
   */

  function errorTrackerReport() {
    // --------  js error ---------
    var originOnError = window.onerror;

    window.onerror = function (msg, url, row, col, error) {
      // 处理原有的onerror
      if (originOnError) {
        originOnError.call(window, msg, url, row, col, error);
      } // 错误上报


      lazyReport('error', {
        message: msg,
        file: url,
        row: row,
        col: col,
        error: String(error),
        errorType: 'jsError'
      });
    }; // ------  promise error  --------


    window.addEventListener('unhandledrejection', function (error) {
      error.preventDefault();
      lazyReport('error', {
        message: formatError(error.reason),
        error: error,
        errorType: 'promiseError'
      });
    }); //格式化Error

    function formatError(error) {
      if (error instanceof Error) {
        return JSON.stringify({
          name: error.name,
          message: error.message,
          stack: error.stack // 包含代码位置的关键信息

        }, null, 2);
      }

      return String(error); // 非Error对象的回退方案
    } // ------- resource error --------


    window.addEventListener('error', function (error) {
      var target = error.target;
      var isElementTarget = target instanceof HTMLScriptElement || target instanceof HTMLLinkElement || target instanceof HTMLImageElement;

      if (!isElementTarget) {
        return; // js error不再处理
      }

      lazyReport('error', {
        message: "加载 " + target.tagName + " 资源错误",
        file: target.src,
        errorType: 'resourceError'
      });
    }, true);
  }
  /**
   * 手动捕获错误
   */

  function errorCaptcher(error, msg) {
    // 上报错误
    lazyReport('error', {
      message: msg,
      error: error,
      errorType: 'catchError'
    });
  }

  function report(data) {
    lazyReport('http', data);
  } // 初始化监控

  function httpTrackerReport(regx) {
    interceptXHR(regx);
    interceptFetch(regx);
  } // XMLHttpRequest 拦截

  function interceptXHR(resRegx) {
    if (typeof XMLHttpRequest === 'undefined') return;
    var originalOpen = XMLHttpRequest.prototype.open;
    var originalSend = XMLHttpRequest.prototype.send;

    XMLHttpRequest.prototype.open = function (method, url) {
      this._method = method;
      this._url = url;
      return originalOpen.apply(this, arguments);
    };

    XMLHttpRequest.prototype.send = function (body) {
      var _this = this;

      var startTime = Date.now();

      var onLoadend = function onLoadend() {
        var _this$responseText;

        var duration = Date.now() - startTime; // 请求数据处理

        var request = handleBody(body);
        var error = '';

        if (_this.status !== 200 || resRegx.test(_this.responseText)) {
          error = error = catResponse(_this.responseText);
        }

        report({
          type: 'xhr',
          method: _this._method,
          url: _this._url,
          status: _this.status,
          duration: duration,
          error: error,
          request: request,
          requestSize: body ? body.length : 0,
          responseSize: ((_this$responseText = _this.responseText) === null || _this$responseText === void 0 ? void 0 : _this$responseText.length) || 0
        });

        _this.removeEventListener('loadend', onLoadend);
      };

      this.addEventListener('loadend', onLoadend);
      return originalSend.apply(this, arguments);
    };
  } // Fetch 拦截

  function interceptFetch(resRegx) {
    if (typeof fetch === 'undefined') return;
    var originalFetch = window.fetch;

    window.fetch = /*#__PURE__*/function () {
      var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(input, init) {
        var startTime, url, method, request, _init$body, response, duration, clonedResponse, responseText, error, _duration;

        return _regeneratorRuntime().wrap(function _callee$(_context) {
          while (1) {
            switch (_context.prev = _context.next) {
              case 0:
                startTime = Date.now();
                url = typeof input === 'string' ? input : input.url;
                method = ((init === null || init === void 0 ? void 0 : init.method) || 'GET').toUpperCase();
                request = handleBody(init === null || init === void 0 ? void 0 : init.body);
                _context.prev = 4;
                _context.next = 7;
                return originalFetch(input, init);

              case 7:
                response = _context.sent;
                duration = Date.now() - startTime; // 克隆响应以读取数据

                clonedResponse = response.clone();
                _context.next = 12;
                return clonedResponse.text();

              case 12:
                responseText = _context.sent;
                error = '';

                if (response.status !== 200 || resRegx.test(responseText)) {
                  error = catResponse(responseText);
                }

                report({
                  type: 'fetch',
                  method: method,
                  url: url,
                  status: response.status,
                  duration: duration,
                  error: error,
                  request: request,
                  requestSize: (init === null || init === void 0 ? void 0 : (_init$body = init.body) === null || _init$body === void 0 ? void 0 : _init$body.length) || 0,
                  responseSize: new Blob([responseText]).size
                });
                return _context.abrupt("return", response);

              case 19:
                _context.prev = 19;
                _context.t0 = _context["catch"](4);
                _duration = Date.now() - startTime;
                report({
                  type: 'fetch',
                  method: method,
                  url: url,
                  status: 0,
                  // 网络错误
                  duration: _duration,
                  error: catResponse(_context.t0.message)
                });
                throw _context.t0;

              case 24:
              case "end":
                return _context.stop();
            }
          }
        }, _callee, null, [[4, 19]]);
      }));

      return function (_x, _x2) {
        return _ref.apply(this, arguments);
      };
    }();
  }

  function handleBody(body) {
    if (body instanceof FormData) {
      return processFormData(body);
    } else {
      return processBodyData(body);
    }
  }

  function processFormData(formData) {
    if (!formData) {
      return formData;
    }

    var body = {};

    try {
      var _iterator = _createForOfIteratorHelper(formData.entries()),
          _step;

      try {
        for (_iterator.s(); !(_step = _iterator.n()).done;) {
          var _step$value = _slicedToArray(_step.value, 2),
              name = _step$value[0],
              value = _step$value[1];

          var data = value;

          if (data) {
            if (data instanceof File) {
              var file = {
                fileName: name,
                fileType: data.type,
                fileSize: data.size,
                lastModified: data.lastModified
              };
              body[name] = file;
            } else if (typeof data === "string" && data.length > 100) {
              body[name] = data.substring(0, 100);
            }
          }
        }
      } catch (err) {
        _iterator.e(err);
      } finally {
        _iterator.f();
      }
    } catch (error) {
      body = formData;
    }

    return body;
  }

  function processBodyData(bodyData) {
    if (!bodyData) {
      return bodyData;
    }

    var body = "";

    try {
      body = JSON.parse(bodyData);
      Object.keys(body).forEach(function (item) {
        var data = body[item];

        if (data) {
          if (data instanceof File) {
            var file = {
              fileName: data.name,
              fileType: data.type,
              fileSize: data.size,
              lastModified: data.lastModified
            };
            body[item] = file;
          } else if (typeof data === "string" && data.length > 100) {
            body[item] = data.substring(0, 100);
          }
        }
      });
    } catch (error) {
      if (typeof bodyData === "string") {
        body = bodyData.substring(0, 500);
      } else {
        body = bodyData;
      }
    }

    return body;
  }

  function catResponse(response) {
    if (response) {
      if (_typeof(response) == "object") {
        var str = JSON.stringify(response);
        return str.substring(0, 500);
      } else {
        return response.substring(0, 500);
      }
    }

    return "";
  }

  /**
   * 加载配置
   * @param {*} options 
   */

  function loadConfig(options) {
    var appId = options.appId,
        userId = options.userId,
        reportUrl = options.reportUrl,
        autoTracker = options.autoTracker,
        delay = options.delay,
        hashPage = options.hashPage,
        errorReport = options.errorReport,
        httpReport = options.httpReport,
        responseRegex = options.responseRegex; // --------- appId ----------------

    if (appId) {
      window['_monitor_app_id_'] = appId;
    } // --------- userId ----------------


    if (userId) {
      window['_monitor_user_id_'] = userId;
    } // --------- 服务端地址 ----------------


    if (reportUrl) {
      window['_monitor_report_url_'] = reportUrl;
    } // -------- 合并上报的间隔 ------------


    if (delay) {
      window['_monitor_delay_'] = delay;
    } // --------- 是否开启错误监控 ------------


    if (errorReport) {
      errorTrackerReport();
    } // --------- 是否开启网络请求监控 ------------


    if (httpReport) {
      httpTrackerReport(responseRegex);
    } // --------- 是否开启无痕埋点 ----------


    if (autoTracker) {
      autoTrackerReport();
    } // ----------- 路由监听 --------------


    if (hashPage) {
      hashPageTrackerReport(); // hash路由上报
    } else {
      historyPageTrackerReport(); // history路由上报
    }
  }
  var getPathTo = function getPathTo(element) {
    if (element.id !== '') return '//*[@id="' + element.id + '"]';
    if (element === document.body) return element.tagName;
    var ix = 0;

    if (element && element.parentNode && element.parentNode.childNodes) {
      var _element$parentNode;

      var siblings = element === null || element === void 0 ? void 0 : (_element$parentNode = element.parentNode) === null || _element$parentNode === void 0 ? void 0 : _element$parentNode.childNodes;

      for (var i = 0; i < siblings.length; i++) {
        var sibling = siblings[i];
        if (sibling === element) return getPathTo(element.parentNode) + '/' + element.tagName + '[' + (ix + 1) + ']';
        if (sibling.nodeType === 1 && sibling.tagName === element.tagName) ix++;
      }
    } else {
      return null;
    }
  };
  var getPathTo2 = function getPathTo2(element) {
    if (!element) return {
      node: "",
      path: ""
    }; // 基础结果对象 - 确保node永远有值

    var result = {
      node: element.nodeName,
      path: "",
      className: element.className // 直接获取元素自身的类名

    }; // 添加元素特定属性

    if (element.tagName === "BUTTON") {
      // 获取按钮的文本内容（包括所有子元素）
      result.textContent = element.textContent || ""; // return result
    } else if (element.tagName === "IMG") {
      var img = element;
      result.src = "";
      result.alt = img.alt || "";
    } // 处理有ID的元素


    if (element.id) {
      return _objectSpread2(_objectSpread2({}, result), {}, {
        path: "//*[@id=\"".concat(element.id, "\"]")
      });
    } // 处理body元素


    if (element === document.body) {
      return _objectSpread2(_objectSpread2({}, result), {}, {
        path: "BODY"
      });
    } // 处理html元素


    if (element === document.documentElement) {
      return _objectSpread2(_objectSpread2({}, result), {}, {
        path: "HTML"
      });
    } // 没有父元素的情况


    if (!element.parentElement) {
      return _objectSpread2(_objectSpread2({}, result), {}, {
        path: element.tagName
      });
    } // 只考虑元素节点 (Node.ELEMENT_NODE)


    var siblings = Array.from(element.parentElement.children).filter(function (sibling) {
      return sibling.nodeType === Node.ELEMENT_NODE;
    });

    for (var i = 0; i < siblings.length; i++) {
      var sibling = siblings[i];

      if (sibling === element) {
        // found = true;
        // 递归获取父元素路径
        var parentResult = getPathTo(element.parentElement);

        if (!parentResult) {
          return result;
        }

        var tagName = element.tagName; // 计算相同类型元素的位置

        var sameTypeIndex = 1;

        for (var j = 0; j < i; j++) {
          if (siblings[j].tagName === element.tagName) {
            sameTypeIndex++;
          }
        }

        var path = (parentResult === null || parentResult === void 0 ? void 0 : parentResult.path) || parentResult;

        if (path.includes('BUTTON')) {
          var textContent = element.textContent;
          return _objectSpread2(_objectSpread2({}, result), {}, {
            textContent: textContent,
            node: 'BUTTON',
            // 路径格式: 父路径/标签名[相同类型索引]
            path: "".concat(path, "/").concat(tagName, "[").concat(sameTypeIndex, "]")
          });
        } else {
          var src = element.src;
          return _objectSpread2(_objectSpread2({}, result), {}, {
            src: src,
            // 路径格式: 父路径/标签名[相同类型索引]
            path: "".concat(path, "/").concat(tagName, "[").concat(sameTypeIndex, "]")
          });
        }
      }
    } // 如果没有找到元素（理论上不应该发生）


    return _objectSpread2(_objectSpread2({}, result), {}, {
      path: element.tagNames
    });
  };
  var getImgButtonPath = function getImgButtonPath(element) {
    var data = getPathTo2(element);

    if (data.path && (data.path.includes('IMG') || data.path.includes('BUTTON'))) {
      if (data.src) {
        data.src = data.src.substring(0, 100);
      }

      return data;
    } else {
      return null;
    }
  };

  var WebMonitorSDK = /*#__PURE__*/function () {
    function WebMonitorSDK() {
      var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

      _classCallCheck(this, WebMonitorSDK);

      this.options = options;
      this.deviceId = this.initializeDeviceId();
    } // 初始化设备ID


    _createClass(WebMonitorSDK, [{
      key: "initializeDeviceId",
      value: function initializeDeviceId() {
        return this.getIDFromStorage() || this.getWindowNameID() || this.generateNewDeviceId();
      } // 多级存储查找（新增sessionStorage）

    }, {
      key: "getIDFromStorage",
      value: function getIDFromStorage() {
        return this.readStorage('localStorage') || this.readStorage('sessionStorage') || this.readCookie();
      } // 统一存储接口

    }, {
      key: "readStorage",
      value: function readStorage(type) {
        try {
          return window[type].getItem('_mon_device_id');
        } catch (e) {
          return null;
        }
      } // Cookie读取（带兼容处理）

    }, {
      key: "readCookie",
      value: function readCookie() {
        try {
          var match = document.cookie.match('(^|;)\\s*_mon_device_id\\s*=\\s*([^;]+)');
          return match ? decodeURIComponent(match[2]) : null;
        } catch (e) {
          return null;
        }
      } // 使用window.name作为跨会话后备存储

    }, {
      key: "getWindowNameID",
      value: function getWindowNameID() {
        try {
          if (window.name && /^mondevid-[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(window.name)) {
            return window.name.split('mondevid-')[1];
          }
        } catch (e) {}

        return null;
      } // 生成新ID（带类型后缀）

    }, {
      key: "generateNewDeviceId",
      value: function generateNewDeviceId() {
        console.log(this.createUUID(), 'this.createUUID()');
        var deviceId = "".concat(this.createUUID(), "-").concat(this.getStorageTypeSuffix());
        this.saveIDToStorage(deviceId);
        this.saveWindowName(deviceId);
        return deviceId;
      } // 获取存储类型后缀

    }, {
      key: "getStorageTypeSuffix",
      value: function getStorageTypeSuffix() {
        if (this.isStorageAvailable('localStorage')) return 'ls';
        if (this.isStorageAvailable('sessionStorage')) return 'ss';
        if (this.isCookieAvailable()) return 'ck';
        return 'mem';
      } // 检测存储可用性

    }, {
      key: "isStorageAvailable",
      value: function isStorageAvailable(type) {
        try {
          var storage = window[type];
          storage.setItem('test', 'test');
          storage.removeItem('test');
          return true;
        } catch (e) {
          return false;
        }
      } // 检测Cookie可用性

    }, {
      key: "isCookieAvailable",
      value: function isCookieAvailable() {
        try {
          document.cookie = 'test=1;SameSite=Lax';
          return document.cookie.indexOf('test=') !== -1;
        } catch (e) {
          return false;
        }
      } // 统一保存到所有可用存储

    }, {
      key: "saveIDToStorage",
      value: function saveIDToStorage(deviceId) {
        this.saveToStorage('localStorage', deviceId);
        this.saveToStorage('sessionStorage', deviceId);
        this.saveCookie(deviceId);
      } // 通用存储保存方法

    }, {
      key: "saveToStorage",
      value: function saveToStorage(type, deviceId) {
        try {
          window[type].setItem('_mon_device_id', deviceId);
        } catch (e) {}
      } // Cookie保存（带特性检测）

    }, {
      key: "saveCookie",
      value: function saveCookie(deviceId) {
        try {
          if (!navigator.cookieEnabled) return;
          var date = new Date();
          date.setFullYear(date.getFullYear() + 1);
          document.cookie = "_mon_device_id=".concat(encodeURIComponent(deviceId), ";expires=").concat(date.toUTCString(), ";path=/;SameSite=Lax");
        } catch (e) {}
      } // 保存到window.name（作为最后后备）

    }, {
      key: "saveWindowName",
      value: function saveWindowName(deviceId) {
        try {
          window.name = "mondevid-".concat(deviceId);
        } catch (e) {}
      } // 生成UUID（RFC4122兼容）

    }, {
      key: "createUUID",
      value: function createUUID() {
        var cryptoObj = window.crypto || window.msCrypto;

        if (cryptoObj && cryptoObj.getRandomValues) {
          var buffer = new Uint16Array(8);
          cryptoObj.getRandomValues(buffer);
          return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
            var r = (buffer[0] + performance.now()) % 16 | 0;
            buffer[0] = r;
            return (c === 'x' ? r : r & 0x3 | 0x8).toString(16);
          });
        }

        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
          var r = Math.random() * 16 | 0;
          var v = c === 'x' ? r : r & 0x3 | 0x8;
          return v.toString(16);
        });
      } // 重置设备ID

    }, {
      key: "resetDeviceId",
      value: function resetDeviceId() {
        var newId = this.generateNewDeviceId();
        this.deviceId = newId;
      }
    }]);

    return WebMonitorSDK;
  }();

  /**
   * 添加用户的额外信息
   * @param {string} info 
   */
  function extraUserInfo(info) {
    if (info) {
      window["_monitor_user_info_"] = info;
    }
  }

  /**
   * 初始化配置
   * @param {*} options 
   */

  function init(options) {
    // ------- 加载配置 ----------
    // 1.拿到配置信息 
    // 2.注入监控代码
    loadConfig(options); // -------- uv统计 -----------

    lazyReport('user', '加载应用'); // ------ 防止卸载时还有剩余的埋点数据没发送 ------

    window.addEventListener('unload', function () {
      var data = getCache();
      report$1(data); // if (data.length > 0) {
      //   report(data);
      // }
    });
  }

  var monitor = new WebMonitorSDK({});
  var deviceId = monitor.deviceId;

  exports.deviceId = deviceId;
  exports.errorCaptcher = errorCaptcher;
  exports.extraUserInfo = extraUserInfo;
  exports.init = init;
  exports.tracker = tracker;

  Object.defineProperty(exports, '__esModule', { value: true });

}));
